package com.starblink.imgsearch.findsimilar.ui.fragment

import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.apollographql.apollo3.api.ApolloResponse
import com.apollographql.apollo3.api.Optional
import com.starblink.android.basic.base.BaseViewModel
import com.starblink.android.basic.config.PAGE_SIZE
import com.starblink.android.basic.data.model.product.ProductFWrap
import com.starblink.android.basic.extension.apollo.toWrap
import com.starblink.android.basic.network.base.SkGqlClient
import com.starblink.basic.apollo.ext.optional
import com.starblink.imgsearch.findsimilar.data.SimilarEmptyBodyModel
import com.starblink.imgsearch.findsimilar.data.SimilarLoadingModel
import com.starblink.imgsearch.result.data.ForYouTitleModel
import com.starblink.imgsearch.result.data.ResultTipModel
import com.starblink.imgsearch.result.data.SeeMoreItemModel
import com.starblink.library.widget.loading.GoodsCardLoadingCell
import com.starblink.rocketreserver.*
import com.starblink.rocketreserver.fragment.ProductF
import com.starblink.rocketreserver.type.PicSearchQuery
import com.starblink.rocketreserver.type.RecommendProductWhenSearchByPicNoResultParam
import com.starblink.rocketreserver.type.SimilarProductSearchParam
import kotlinx.coroutines.Job
import kotlinx.coroutines.async
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

internal class SimilarTabViewModel : BaseViewModel() {


    val tipItem = ResultTipModel(0.0)

    val emptyBodyModel = SimilarEmptyBodyModel("empty")

    val loadingModel = SimilarLoadingModel("loading")

    val adapterList = arrayListOf<Any>()

    /**
     * 结果list集合
     */
    val products = arrayListOf<ProductFWrap>()

    val resultLD = MutableLiveData<List<ProductFWrap>>()

    val mainPrdLD = MutableLiveData<ProductF>()

    val loadStateLD = MutableLiveData<Int>()

    var pageNo = 1

    var picUrl = ""

    var regin = ""

    var productId = ""

    var type = 1

    private var initRequestJob: Job?= null


    val loadingData = arrayListOf<Any>().apply {
        add(loadingModel)
        addAll(GoodsCardLoadingCell.LOADING_DATA)
    }

    fun initAdapterList() {
        adapterList.run {
            if (products.isNotEmpty()) {
                add(0, tipItem.apply {
                    firstScore = products.firstOrNull()?.productF?.score ?: 0.0
                    visible = products.isNotEmpty()
                })
                addAll(products)
            }
        }
    }

    fun loadMoreContent() {
        pageNo++
        viewModelScope.launch {
            val response = loadData()
            response?.productList?.mapIndexed { index, it ->  it.productF.toWrap(products.size + index) }?.let { it ->
                products.addAll(it)
                resultLD.postValue(it)
            }
            loadStateLD.postValue(LOAD_STATE_FINISH)
        }
    }

    /**
     * 初始化数据优先请求结果，再请求推荐
     */
    fun loadInitData() {
        initRequestJob = viewModelScope.async {
            loadData()?.let { it ->
                val list = it.productList?.mapIndexed { index, it ->  it.productF.toWrap(products.size + index) } ?: emptyList()
                products.addAll(list)
                resultLD.postValue(list)
                if (pageNo == 1) {
                    mainPrdLD.postValue(it.currentProduct?.productF)
                }
            }

        }
    }

    private suspend fun loadData(): SearchSimilarProductByPicQuery.SearchSimilarProductByPic? =
        SkGqlClient.skQuery(
            query = SearchSimilarProductByPicQuery(
                param = SimilarProductSearchParam(
                    mainPic = picUrl,
                    region = regin.optional(),
                    id = productId,
                    type = type,
                    pageNo = pageNo,
                    pageSize = PAGE_SIZE.optional(),
                )
            )
        )?.data?.searchSimilarProductByPic


    fun resetData() {
        pageNo = 1

        adapterList.clear()
        products.clear()
        initRequestJob?.cancel()
    }

    companion object {
        const val LOAD_STATE_FINISH = 100
    }


}